-- Group B Transmit Team
-- February 24, 2007
-- This file is a package file describing the port map to a framepointer

Library ieee;
Use ieee.std_logic_1164.all;

Package transmit_package Is
	Component framepointer
		Port(MoveInAddr					: In Std_logic_vector(8 downto 0);
			 MoveInCRC					: In Std_logic;
			 MoveInTag					: In Std_logic_vector(31 downto 0);
			 Clock, Move, Set			: In Std_logic;
			 WriteInAddr				: In Std_logic_vector(8 downto 0);
			 WriteInCRC					: In Std_logic;
			 WriteInTag					: In Std_logic_vector(31 downto 0);
			 OutputAddr					: Out Std_logic_vector(8 downto 0);
			 OutputCRC					: Out Std_logic;
			 OutputTag					: Out Std_logic_vector(31 downto 0));
	End Component;
	
	Component framenibble
		Port(MoveInNibble				: In Std_logic_vector(3 downto 0);
			 Clock, Move, Set			: In Std_logic;
			 Choose						: In Std_logic_vector(3 downto 0);
			 WriteInNibble0				: In Std_logic_vector(3 downto 0);
			 WriteInNibble1				: In Std_logic_vector(3 downto 0);
			 WriteInNibble2				: In Std_logic_vector(3 downto 0);
			 WriteInNibble3				: In Std_logic_vector(3 downto 0);
			 OutputNibble				: Out Std_logic_vector(3 downto 0));
	End Component;
	
	Function bitAnd(b: Std_logic; v: Std_logic_vector(9 downto 0)) Return Std_logic_vector;
	
	Function move(v: Std_logic_vector(15 downto 0)) Return Std_logic_vector;
	
	Function forward(v: Std_logic_vector(16 downto 0)) Return std_logic_vector;
	
	Function backward(v: Std_logic_vector(16 downto 0)) Return std_logic_vector;
	
	Function equal(int1: Integer; int2: Integer) Return std_logic;
	
	Function to_int(a: std_logic_vector) return Integer;
	
	Function nextCRC32(Data: std_logic_vector; CRC: std_logic_vector) return std_logic_vector;

End transmit_package;

Package Body transmit_package Is
-- Function utilized in Generate statement
Function bitAnd(b: Std_logic; v: Std_logic_vector(9 downto 0)) Return Std_logic_vector Is
	Variable result: Std_logic_vector(9 downto 0);
Begin
	For i In 0 to 9 Loop
		result(i) := (b And v(i));
	End Loop;
	Return result;
End Function;
	
-- Function utilized for re-arranging pointer to front and back of buffer	
Function move(v: Std_logic_vector(15 downto 0)) Return std_logic_vector Is
	Variable result: Std_logic_vector(15 downto 0);
Begin
	result(0) := v(15);
	For i In 0 to 14 Loop
		result(i+1) := v(i);
	End Loop;
	Return result;
End Function;

Function forward(v: Std_logic_vector(16 downto 0)) Return std_logic_vector Is
	Variable result: Std_logic_vector(16 downto 0);
Begin
	result(16) := '0';
	For i In 0 to 15 Loop
		result(i) := v(i+1);
	End Loop;
	Return result;
End Function;

Function backward(v: Std_logic_vector(16 downto 0)) Return std_logic_vector Is
	Variable result: Std_logic_vector(16 downto 0);
Begin
	result(0) := '0';
	For i In 0 to 15 Loop
		result(i+1) := v(i);
	End Loop;
	Return result;
End Function;

Function equal(int1: Integer; int2: Integer) Return std_logic Is
	Variable result: Std_logic;
Begin
	If int1 = int2 Then
		result := '1';
	Else
		result := '0';
	End If;
	Return result;
End Function;

function to_int (a: std_logic_vector) return integer is
	alias av: std_logic_vector (a'length downto 1) is a;
        variable val: integer := 0;
        variable b: integer := 1;
        variable s: integer := 1;  -- sign
    begin
    	if (av(1) = '1') then
    		s := -1;
	end if;
        for i in a'length downto 1 loop
            if (av(i) = '1' and s=1) then    -- if LSB is '1',
                val := val + b;      -- add value for current bit position
            end if;
            if (av(i) = '0' and s=-1) then
            		val := val + b;
            end if;
            b := b * 2;              -- Shift left 1 bit
        end loop;
        if (s = -1) then
        		val := val + 1;
	end if;
        val := val * s;
        return val;
 end function;

function nextCRC32  
    ( Data:  std_logic_vector(3 downto 0);
      CRC:   std_logic_vector(31 downto 0) )
    return std_logic_vector is

    variable D: std_logic_vector(3 downto 0);
    variable C: std_logic_vector(31 downto 0);
    variable NewCRC: std_logic_vector(31 downto 0);

  begin

    D := Data;
    C := CRC;

    NewCRC(0) := D(0) xor C(28);
    NewCRC(1) := D(1) xor D(0) xor C(28) xor C(29);
    NewCRC(2) := D(2) xor D(1) xor D(0) xor C(28) xor C(29) xor C(30);
    NewCRC(3) := D(3) xor D(2) xor D(1) xor C(29) xor C(30) xor C(31);
    NewCRC(4) := D(3) xor D(2) xor D(0) xor C(0) xor C(28) xor C(30) xor 
                 C(31);
    NewCRC(5) := D(3) xor D(1) xor D(0) xor C(1) xor C(28) xor C(29) xor 
                 C(31);
    NewCRC(6) := D(2) xor D(1) xor C(2) xor C(29) xor C(30);
    NewCRC(7) := D(3) xor D(2) xor D(0) xor C(3) xor C(28) xor C(30) xor 
                 C(31);
    NewCRC(8) := D(3) xor D(1) xor D(0) xor C(4) xor C(28) xor C(29) xor 
                 C(31);
    NewCRC(9) := D(2) xor D(1) xor C(5) xor C(29) xor C(30);
    NewCRC(10) := D(3) xor D(2) xor D(0) xor C(6) xor C(28) xor C(30) xor 
                  C(31);
    NewCRC(11) := D(3) xor D(1) xor D(0) xor C(7) xor C(28) xor C(29) xor 
                  C(31);
    NewCRC(12) := D(2) xor D(1) xor D(0) xor C(8) xor C(28) xor C(29) xor 
                  C(30);
    NewCRC(13) := D(3) xor D(2) xor D(1) xor C(9) xor C(29) xor C(30) xor 
                  C(31);
    NewCRC(14) := D(3) xor D(2) xor C(10) xor C(30) xor C(31);
    NewCRC(15) := D(3) xor C(11) xor C(31);
    NewCRC(16) := D(0) xor C(12) xor C(28);
    NewCRC(17) := D(1) xor C(13) xor C(29);
    NewCRC(18) := D(2) xor C(14) xor C(30);
    NewCRC(19) := D(3) xor C(15) xor C(31);
    NewCRC(20) := C(16);
    NewCRC(21) := C(17);
    NewCRC(22) := D(0) xor C(18) xor C(28);
    NewCRC(23) := D(1) xor D(0) xor C(19) xor C(28) xor C(29);
    NewCRC(24) := D(2) xor D(1) xor C(20) xor C(29) xor C(30);
    NewCRC(25) := D(3) xor D(2) xor C(21) xor C(30) xor C(31);
    NewCRC(26) := D(3) xor D(0) xor C(22) xor C(28) xor C(31);
    NewCRC(27) := D(1) xor C(23) xor C(29);
    NewCRC(28) := D(2) xor C(24) xor C(30);
    NewCRC(29) := D(3) xor C(25) xor C(31);
    NewCRC(30) := C(26);
    NewCRC(31) := C(27);

    return NewCRC;

  end function;

End Package Body;